/**
* Copyright (c) By zengqh.
*
* This program is just for fun or demo, in the hope that it  
* will be useful, you can redistribute it and/or modify freely.
*
* Time: 2012/07/11
* File: Rect.h
* Blog: http://www.cnblogs.com/zengqh/
**/

#ifndef Rect_h__
#define Rect_h__

#include "Rfstd.h"

template <typename T>
class Rect
{
public:
	Rect()
		: _left_top(0, 0)
		, _right_bottom(0, 0)
	{

	}

	Rect(T x1, T y1, T x2, T y2)
		: _left_top(x1, y1)
		, _right_bottom(x2, y2)
	{

	}

	Rect(const glm::detail::tvec2<T>& left_top,
		glm::detail::tvec2<T>& right_bottom)
		: _left_top(left_top)
		, _right_bottom(right_bottom)
	{

	}

	Rect<T> operator+(const glm::detail::tvec2<T>& offset) const
	{
		Rect<T> ret(*this);
		ret += offset;

		return ret;
	}

	Rect<T> operator+=(const glm::detail::tvec2<T>& offset)
	{
		_left_top += offset;
		_right_bottom += offset;
	}

	Rect<T> operator-(const glm::detail::tvec2<T>& offset) const
	{
		Rect<T> ret(*this);
		ret -= offset;

		return ret;
	}

	Rect<T> operator-=(const glm::detail::tvec2<T>& offset)
	{
		_left_top -= offset;
		_right_bottom -= offset;
	}

	bool operator==(const Rect<T>& other) const
	{
		return _left_top == other._left_top && _right_bottom == other._right_bottom;
	}

	T getWidth() const
	{
		return _right_bottom.x - _left_top.x;
	}

	T getHeight() const
	{
		return _right_bottom.y - _left_top.y;
	}

	T getArea() const
	{
		return getWidth() * getHeight();
	}

	bool isPointInside(const glm::detail::tvec2<T>& pos) const
	{
		return (_left_top.x <= pos.x &&
			_left_top.y <= pos.y &&
			_right_bottom.x >= pos.x &&
			_right_bottom.y >= pos.y);
	}

	/* wrong */
	bool isRectIntersect(const Rect<T>& other) const
	{
		return (_right_bottom.y > other._left_top.y &&
			_left_top.y < other._right_bottom.y &&
			_right_bottom.x > other._left_top.x &&
			_left_top.x < other._right_bottom.x);
	}

	void repair()
	{
		if (_right_bottom.x < _left_top.x)
		{
			T t = _right_bottom.x;
			_right_bottom.x = _left_top.x;
			_left_top.x = t;
		}

		if (_right_bottom.y < _left_top.y)
		{
			T t = _right_bottom.y;
			_right_bottom.y = _left_top.y;
			_left_top.y = t;
		}
	}

	glm::detail::tvec2<T> getCenter() const
	{
		return glm::detail::tvec2<T>(
			(_left_top.x + _right_bottom.x) / 2, 
			(_left_top.y + _right_bottom.y) / 2);
	}


	glm::detail::tvec2<T>		_left_top;
	glm::detail::tvec2<T>		_right_bottom;
};

typedef Rect<s32>	Recti;
typedef Rect<f32>	Rectf;
typedef Rect<f64>	Rectd;


#endif    /* Rect_h__ */